SurfaceControl事务提交过程

综述

SurfaceControl,顾明思议它是Surface的控制管理者,我们知道Surface是应用层用户进行UI绘制的绘图表面,它由WindowManagerService创建,WindowManagerService管理着窗口对象WindowState,Window是一个抽象的概念,它属于设计层面使用的类,而Surface实际上才是实现上的窗口实体。所以当WMS对Window做了改变,比如调整layerStack,Z-order,大小,位置等后需要通过SurfaceControl来告知SurfaceFlinger,以便SurfaceFlinger更新其在SF端的Layer图层进行合成渲染,这个Layer图层实际上和应用层使用的Surface是对应的。本篇我们将通过SuraceControl来了解这些属性更新的具体过程。

SurfaceControl的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
....
try {
if (!win.mHasSurface) {
surfaceChanged = true;
}
//创建SurfaceControl 准备画布
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
if (surfaceControl != null) {
outSurface.copyFrom(surfaceControl);//Surface从SurfaceControl中得到
if (SHOW_TRANSACTIONS) Slog.i(TAG,
" OUT SURFACE " + outSurface + ": copied");
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
outSurface.release();
}
} catch (Exception e) {}
....
}

在之前介绍创建Surface的流程中我们知道SurfaceControl的创建过程是在WMS的relayoutWindow方法中进行的,Surface是从SurfaceControl中取到的。它实际是通过WindowStateAnimator的createSurfaceLocked创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
SurfaceControl createSurfaceLocked() {
....
//创建SurfaceControl
mSurfaceControl = new SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
w, h, format, flags);
....

//这里通过SurfaceControl的transaction来提交Surface的设置
SurfaceControl.openTransaction();
try {
try {
mSurfaceX = mWin.mFrame.left + mWin.mXOffset;
mSurfaceY = mWin.mFrame.top + mWin.mYOffset;
mSurfaceControl.setPosition(mSurfaceX, mSurfaceY);//设置position
mSurfaceLayer = mAnimLayer;
mSurfaceControl.setLayerStack(mLayerStack);//设置layerStack
mSurfaceControl.setLayer(mAnimLayer);//设置Z order
mSurfaceControl.setAlpha(0);//设置透明度 0?
mSurfaceShown = false;
} catch (RuntimeException e) {
Slog.w(TAG, "Error creating surface in " + w, e);
mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
}
mLastHidden = true;
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION createSurfaceLocked");
}
...
}

WindowStateAnimator的createSurfaceLocked负责创建SurfaceControl对象,同时会开启一个事务来提交surface的初始属性。属性的设置是通过SurfaceControl的一系列set方法进行设置的。事务过程通过openTransaction和closeTransaction来控制。

属性设置和事务提交

下面我们就具体分析这两个方法是如何进行属性设置和事务提交的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SurfaceControl {
/** start a transaction */
public static void openTransaction() {
nativeOpenTransaction();
}

/** end a transaction */
public static void closeTransaction() {
nativeCloseTransaction();
}

public void setLayer(int zorder) {
checkNotReleased();
nativeSetLayer(mNativeObject, zorder);
}

}

这里我们看的是Z-order的属性设置,属性的设置和提交都是通过JNI层进行一步处理的,我们接着看android_view_SurfaceControl.cpp中的JNI实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

static void nativeSetLayer(JNIEnv* env, jclass clazz, jint nativeObject, jint zorder) {
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
status_t err = ctrl->setLayer(zorder);
if (err < 0 && err != NO_INIT) {
doThrowIAE(env);
}
}

//开启事务
static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
SurfaceComposerClient::openGlobalTransaction();
}

//提交事务
static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
SurfaceComposerClient::closeGlobalTransaction();
}

属性设置通过native层的SurfaceControl来设置,提交实际上是经过SurfaceComposerClient处理,之前我们在介绍Surface创建流程是有过介绍,它实际上是SF端的Client在客户端的Binder代理,在WMS中的为应用端创建Session会话时也会构造一个SurfaceSession,这个SurfaceSession实际上就是SurfaceComposerClient在上层的体现。

属性设置

下面我们先看属性是如何设置的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbp)
: mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}

status_t SurfaceControl::setLayer(int32_t layer) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
return client->setLayer(mHandle, layer);
}

在SurfaceControl中属性设置最终还是通过我们创建的SurfaceComposerClient进行处理的,它的构造方法中的client就是我们在SurfaceSession中创建的
SurfaceComposerClient。

1
2
3
4
5
6
7
8
9
10
11
12
13

SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}

inline Composer& SurfaceComposerClient::getComposer() {
return mComposer;
}

status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
return getComposer().setLayer(this, id, z);
}

创建SurfaceComposerClient对象时同时会创建一个mComposer的Composer对象,它是一个单例,我们的属性值最终是通过它来进行设置的,我们看看Composer的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Composer : public Singleton<Composer>
{
friend class Singleton<Composer>;

mutable Mutex mLock;
SortedVector<ComposerState> mComposerStates;
SortedVector<DisplayState > mDisplayStates;
uint32_t mForceSynchronous;
uint32_t mTransactionNestCount;
bool mAnimation;

Composer() : Singleton<Composer>(),
mForceSynchronous(0), mTransactionNestCount(0),
mAnimation(false)
{ }

void openGlobalTransactionImpl();
void closeGlobalTransactionImpl(bool synchronous);
void setAnimationTransactionImpl();

layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& client, const sp<IBinder>& id);

DisplayState& getDisplayStateLocked(const sp<IBinder>& token);

public:
...
status_t setPosition(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float x, float y);
status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t w, uint32_t h);
status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
int32_t z);
status_t setLayerStack(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, uint32_t layerStack);

...

static void setAnimationTransaction() {
Composer::getInstance().setAnimationTransactionImpl();
}

static void openGlobalTransaction() {
Composer::getInstance().openGlobalTransactionImpl();
}

static void closeGlobalTransaction(bool synchronous) {
Composer::getInstance().closeGlobalTransactionImpl(synchronous);
}
};

通过Composer的定义我们可以大概看出其实属性的设置和提交最终都是通过它来进行的。我们先看设置的过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, int32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= layer_state_t::eLayerChanged;
s->z = z;
return NO_ERROR;
}

layer_state_t* Composer::getLayerStateLocked(
const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {

ComposerState s;
s.client = client->mClient;
s.state.surface = id;

ssize_t index = mComposerStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);
}

ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
}

setLayer首先通过getLayerStateLocked获取到一个layer_state_t对象,它保存的了layer的属性信息,layer_state_t实际上是由Composer类的mComposerStates维护的,它是一个SortedVector,即ComposerState的有序集合。我们最终从ComposerState取出layer_state_t,然后将我们设置的属性保存在里面。

提交属性事务

接下来就是提交属性的过程,属性提交通过SurfaceComposerClient的openGlobalTransaction和closeGlobalTransaction
实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void SurfaceComposerClient::openGlobalTransaction() {
Composer::openGlobalTransaction();
}

void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
Composer::closeGlobalTransaction(synchronous);
}

static void openGlobalTransaction() {
Composer::getInstance().openGlobalTransactionImpl();
}

static void closeGlobalTransaction(bool synchronous) {
Composer::getInstance().closeGlobalTransactionImpl(synchronous);
}

它内部实际上是使用Composer的静态方法实现,而在Compser的类定义中我们看到,这两个静态方法的实现实际上是会使用我们为
SurfaceComposerClient创建的单例mComposer来进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void Composer::openGlobalTransactionImpl() {
{ // scope for the lock
Mutex::Autolock _l(mLock);
mTransactionNestCount += 1;
}
}

void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());

Vector<ComposerState> transaction;
Vector<DisplayState> displayTransaction;
uint32_t flags = 0;

{ // scope for the lock
Mutex::Autolock _l(mLock);
mForceSynchronous |= synchronous;
if (!mTransactionNestCount) {
ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior "
"call to openGlobalTransaction().");
} else if (--mTransactionNestCount) {
return;
}

transaction = mComposerStates;
mComposerStates.clear();

displayTransaction = mDisplayStates;
mDisplayStates.clear();

if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}

mForceSynchronous = false;
mAnimation = false;
}

sm->setTransactionState(transaction, displayTransaction, flags);
}

openGlobalTransactionImpl的实现只是更新事务计数值mTransactionNestCount,真正的提交操作是在closeGlobalTransactionImpl,这里的synchronous默认为false。我们之前设置的属性保存在mComposerStates中,这里将其添加到transaction中,并通过ISurfaceComposer的setTransactionState提交给SF。这里ISurfaceComposer是SurfaceFlinger的Binder 本地代理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void SurfaceFlinger::setTransactionState(
const Vector<ComposerState>& state,
const Vector<DisplayState>& displays,
uint32_t flags)
{
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
...
size_t count = displays.size();
for (size_t i=0 ; i<count ; i++) {
const DisplayState& s(displays[i]);
transactionFlags |= setDisplayStateLocked(s);
}

count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
// Here we need to check that the interface we're given is indeed
// one of our own. A malicious client could give us a NULL
// IInterface, or one of its own or even one of our own but a
// different type. All these situations would cause us to crash.
//
// NOTE: it would be better to use RTTI as we could directly check
// that we have a Client*. however, RTTI is disabled in Android.
if (s.client != NULL) {
sp<IBinder> binder = s.client->asBinder();
if (binder != NULL) {
String16 desc(binder->getInterfaceDescriptor());
if (desc == ISurfaceComposerClient::descriptor) {
sp<Client> client( static_cast<Client *>(s.client.get()) );
transactionFlags |= setClientStateLocked(client, s.state);
}
}
}
}

if (transactionFlags) {
// this triggers the transaction
setTransactionFlags(transactionFlags);
...
}
}

在setTransactionState中会通过setClientStateLocked通知SF更新layer的属性。这里会从ComposerState中取出
state,即layer_state_t。设置完成后会通过setTransactionFlags通知SF进行layer属性的变更操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
uint32_t SurfaceFlinger::setClientStateLocked(
const sp<Client>& client,
const layer_state_t& s)
{
uint32_t flags = 0;
sp<Layer> layer(client->getLayerUser(s.surface));
if (layer != 0) {
const uint32_t what = s.what;
if (what & layer_state_t::ePositionChanged) {
if (layer->setPosition(s.x, s.y))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eLayerChanged) {
// NOTE: index needs to be calculated before we update the state
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z)) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
if (what & layer_state_t::eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eAlphaChanged) {
if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eMatrixChanged) {
if (layer->setMatrix(s.matrix))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eTransparentRegionChanged) {
if (layer->setTransparentRegionHint(s.transparentRegion))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eVisibilityChanged) {
if (layer->setFlags(s.flags, s.mask))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCropChanged) {
if (layer->setCrop(s.crop))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eLayerStackChanged) {
// NOTE: index needs to be calculated before we update the state
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayerStack(s.layerStack)) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
}
return flags;
}

setClientStateLocked方法首先通过Client的getLayerUser取出Layer图层,这个图层就是我们为应用端创建Surface时在SF端创建的。它通过SF的addClientLayer添加到Client以及SF的mCurrentState.layersSortedByZ中。所以这里将我们设置的属性值最终更新到SF管理的layer中。

设置完SF中layer的属性后需要通知SF进行layer的属性变更,实际上就是让SF进行一次合成渲染操作以便更新应用界面,这个是通过setTransactionFlags进行的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if ((old & flags)==0) { // wake the server up
signalTransaction();
}
return old;
}
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}

void SurfaceFlinger::onMessageReceived(int32_t what) {//MessageQueue中消息实际是通过SF来处理的
ATRACE_CALL();
if(mDelayFlag) {
usleep(20000);
mDelayFlag = 0;
}
switch (what) {
//处理之前对屏幕和应用程序窗口的改动。因这些改动很有可能会改变图层的可见区域,进而影响脏区域的计算。
case MessageQueue::TRANSACTION:
handleMessageTransaction();
break;

//用于处理Layer或者display属性的变化以及Layer对应buffer的更新
case MessageQueue::INVALIDATE:

handleMessageTransaction();//处理之前对屏幕和应用程序窗口的改动。因这些改动很有可能会改变图层的可见区域,进而影响脏区域的计算。
handleMessageInvalidate();//主要是从各Layer对应的BufferQueue中拿图形缓冲区数据,并根据内容更新脏区域

signalRefresh();//进行刷新
break;
/**
* 表示SurfaceFlinger需要进行一次合成操作(Refresh):
* 1) Layer属性的变化导致window state发生变化;
2) Layer有新的buffer到来;
3) HWC请求进行一次repaint。
*/
case MessageQueue::REFRESH:
handleMessageRefresh();//合并和渲染输出
break;
}
}

signalTransaction会通过SF的MessageQueue安排一次VSYNC信号,从而触发INVALIDATE事件,然后在SF中再通过onMessageReceived处理layer属性变更以及合成和渲染的工作。

坚持原创技术分享,您的支持将鼓励我继续创作!